package com.onpositive.notes.parser;

import java.io.Serializable;
import java.util.HashMap;

public class Block<S> implements Comparable<Block<S>>, Serializable
{
	public Block() {
		super();
	}
	private static final long serialVersionUID = 2220212962067424901L;

	public static final String BLOCK_KIND_UNIT = "UNIT";
	
	public static final String BLOCK_KIND_STRING = "STRING";
	
	public static final String BLOCK_KIND_DATE = "DATE";
	
	public static final String BLOCK_KIND_DIMENSION = "DIMENSION";	

	public static final String BLOCK_KIND_SCALAR = "SCALAR";
	
	public static final String BLOCK_KIND_MARK = "MARK";
	
	public static final String BLOCK_KIND_KEYWORD = "KEYWORD";
	
	public Block(String str, int start, int end, S pVal, String kind ) {
		super();
		this.str = str;
		this.start = start;
		this.end = end;
		this.pVal = pVal ;
		this.kind = kind ;		
	}
	private String str ;
	private int start, end ;
	private HashMap<String,Object> meta ;
	private S pVal ;
	private String kind ;
	
	public<VAL_TYPE> VAL_TYPE getMetaInfo( String key, Class<VAL_TYPE> valClazz ){
		
		if( meta == null )
			return null ;
		
		final Object object = meta.get(key);
		if(!valClazz.isInstance(object)) 
			return null ;
		
		return valClazz.cast(object) ;
	}
	
	public void putMetaInfo( String key, Object value ){
		
		if( meta == null )
			meta = new HashMap<String, Object>() ;
		
		meta.put(key,value) ;
	}

	public int getStart() { return start; }
	public int getEnd() { return end; }
	public S getVal() { return pVal; }

	public String getStr() {
		return str;
	}
	
	public String getKind() {
		return kind;
	}

	@Override
	public String toString()
	{
		StringBuilder bld = new StringBuilder() ;
		bld.append( "Block: " ) ;
		bld.append( getVal().toString() ) ;
		bld.append( " [" ) ;
		bld.append( getStart() ) ;
		bld.append( "," ) ;
		bld.append( getEnd() ) ;
		bld.append( "]" ) ;
		
		return bld.toString() ;
	}

	@Override
	public int compareTo(Block<S> o) {			
		return this.getStart()-o.getStart() ;
	}
	
	public String getSubstring(){
		return str.substring(start, end) ;
	}
	
	public void applyOffset( int off){
		this.start += off ;
		this.end += off ;		
	}
	
	public void setStart( int start ){
		this.start = start ;
	}
	
	public void setEnd( int end ){
		this.end = end ;
	}
}
